S09-05 Webpack5-Gulp、Rollup、Vite
[TOC]
自动化工具 Gulp4
Gulp API
gulp
- 任务组合
- gulp.series():
(task1, task2, ...),按顺序执行任务。- task1...:
string | function,需要按顺序执行的任务名或任务函数。 - 返回:
- tasks:
function,执行任务的函数。
- task1...:
- gulp.parallel():
(task1, task2, ...),并行执行任务。- task1...:
string | function,需要按顺序执行的任务名或任务函数。 - 返回:
- tasks:
function,执行任务的函数。
- task1...:
- 文件操作
- gulp.src():
(glob, options?),读取文件并返回流。- glob:
string | string[],文件模式,支持 glob 匹配。 - options?:
{base,cwd},可选配置,如base和cwd。 - 返回:
- stream:
NodeJS.ReadWriteStream,读取流。
- glob:
- gulp.dest():
(path, options?),将流写入目标目录。- path:
string,目标目录。 - options?:
{base,cwd},可选配置,如base和cwd。 - 返回:
- stream:
NodeJS.ReadWriteStream,可写流。
- path:
- stream.pipe():
(transform),将流传递给下一个处理步骤。常用于插件链式操作。- transform:
stream.Transform,变换流,如插件。
- transform:
- gulp.watch():
(glob, tasks),监视文件变化并重新运行任务。- glob:
string | string[],监视的文件模式。 - tasks:
string | string[] | function,任务名或任务函数。 - 返回:
- gulp-watch:``,监视流。
- glob:
gulp-babel
gulp-babel:是一个 Gulp 插件,用于将 Babel 转换的功能集成到 Gulp 流程中。
API:
- babel():
({plugins?, presets?}),用于将 Babel 转换功能集成到 Gulp 流程中。- plugins?:
array,babel 插件(plugins)的配置对象。 - presets?:
array,babel 预设(presets)的配置对象。 - 返回:
- stream:
Stream,返回一个 Gulp 流对象
- plugins?:
gulp-terser
gulp-terser:是一个用于在 Gulp 构建流程中集成 Terser 的插件,Terser 是一个用于 JavaScript 文件压缩和混淆的工具。
API:
- terser():
({mangle, compress, output}),接收配置选项来控制压缩行为。- mangle:
object,混淆选项- toplevel:
boolean,是否混淆顶级变量和函数 - keep_fnames:
boolean,保留函数名 - keep_cnames:
boolean,保留类名
- toplevel:
- compress:
object,压缩选项- drop_console:
boolean,是否删除 console - arrows:
boolean,是否转换成箭头函数 - arguments:
boolean,是否将 arguments[index]转成对应的形参名称 - dead_code:
boolean,是否移除不可达的代码 - unused:
boolean,是否移除未使用过的函数
- drop_console:
- output:
object,输出选项- comments:
boolean,是否保留注释
- comments:
- 返回:
- stream:
Stream,返回一个 Gulp 流对象
- mangle:
gulp-htmlmin
gulp-htmlmin:是一个用于在使用 Gulp 构建工具时对 HTML 文件进行压缩的插件。它基于 html-minifier 库。
API:
htmlmin():
(options),用于压缩 HTML 文件options:
{collapseWhitespace,...},配置对象,用于指定各种压缩选项。与htmlWebpackPlugins插件的 minify 选项一致。collapseWhitespace: 去除空格removeComments: 删除注释removeEmptyAttributes: 删除空属性removeRedundantAttributes: 删除多余的属性removeScriptTypeAttributes: 删除 script 标签的 type 属性removeStyleLinkTypeAttributes: 删除 style 和 link 标签的 type 属性useShortDoctype: 使用短的 doctype 声明minifyJS: 压缩内嵌的 JavaScript 代码minifyCSS: 压缩内嵌的 CSS 代码
返回:
stream:
Stream,返回一个 Stream 对象,可以将它与其他 Gulp 插件链式调用,以便在管道中处理文件。- js
const gulp = require('gulp') const htmlmin = require('gulp-htmlmin') const rename = require('gulp-rename') gulp.task('minify', () => { return gulp .src('src/*.html') .pipe(htmlmin({ collapseWhitespace: true })) .pipe(rename({ suffix: '.min' })) .pipe(gulp.dest('dist')) })
gulp-less
gulp-less:是一个用于 Gulp 的 LESS 插件,主要用于将 LESS 文件编译成 CSS 文件。
API:
less():
(options?),用于将 LESS 文件编译成 CSS 文件。- options?:
{paths?, plugins?},编译选项。- paths?:
string[],用于 @import 指令的路径数组。 - plugins?:
string[],LESS 插件数组。
- paths?:
- 返回:
- stream:
Stream,返回一个 Stream 对象,可以将它与其他 Gulp 插件链式调用,以便在管道中处理文件。
- options?:
- js
var less = require('gulp-less') var path = require('path') gulp.task('less', function () { return gulp .src('./less/**/*.less') .pipe( less({ paths: [path.join(__dirname, 'less', 'includes')] }) ) .pipe(gulp.dest('./public/css')) })
gulp-inject
gulp-inject:是一个用于 Gulp 的插件,可以将样式表、JavaScript 和 Web 组件的引用注入到 HTML 文件中,避免手动编辑 index.html 文件。
API:
inject():
(source, options?),用于将文件路径注入到 HTML 文件中。source:
stream | string,要注入的文件流或文件路径。通常这是一个 Gulp 任务生成的流,例如gulp.src('path/to/files/*.js')。options?:
object,可选配置对象,用于定制注入行为。- starttag?:
string,默认:<!-- inject:{ {ext} } -->,注入内容的开始标记。 - endtag?:
string,默认:<!-- endinject -->,注入内容的结束标记。 - transform?:
(filepath) => void,自定义处理注入内容的函数。 - ignorePath?:
string | string[],默认:null,用于忽略路径中的部分字符串,以便生成相对路径。 - addRootSlash?:
boolean,默认:true,是否在路径前添加根斜杠。 - relative?:
boolean,默认:false,是否使用相对路径。
- starttag?:
返回:
stream:
Stream,返回一个 Stream 对象,可以将它与其他 Gulp 插件链式调用,以便在管道中处理文件。- js
const inject = require('gulp-inject') const gulp = require('gulp') gulp.task('inject', function () { const sources = gulp.src(['src/**/*.js', 'src/**/*.css'], { read: false }) return gulp .src('src/index.html') .pipe( inject(sources, { starttag: '<!-- inject:{{ext}} -->', endtag: '<!-- endinject -->', transform: function (filepath) { return '<script src="' + filepath + '"></script>' } }) ) .pipe(gulp.dest('dist')) })
browser-sync
browser-sync:是一个用于前端开发的工具,可以帮助你实时刷新浏览器页面。它会监视文件的变化,自动刷新浏览器,提升开发效率。
API:
browserSync.init():
(config, callback?),初始化 BrowserSync 的函数,它接受一个配置对象来定义服务器的行为和特性。config:
object,定义服务器的行为和特性的配置对象。- server:
{baseDir},用于设置静态文件服务器的根目录。 - files:
string[],用于监视文件变化,并自动刷新浏览器。 - port:
number,指定服务器的端口号。 - open:
boolean,是否在启动时自动打开浏览器。 - proxy:
string,用于代理现有的服务器(如本地开发的服务器)。
- server:
callback?:
function,初始化 BrowserSync 完毕后回调的函数。- js
const gulp = require('gulp') const browserSync = require('browser-sync').create() gulp.task('serve', function () { browserSync.init({ server: './app' }) gulp.watch('app/*.html').on('change', browserSync.reload) gulp.watch('app/css/*.css').on('change', browserSync.reload) gulp.watch('app/js/*.js').on('change', browserSync.reload) }) gulp.task('default', gulp.series('serve'))
概述
什么是 Gulp
什么是 Gulp?
A toolkit to automate & enhance your workflow;
一个工具包,可以帮你自动化和增强工作流;

Gulp 和 Webpack
gulp 的核心理念是task runner
可以定义自己的一系列任务,等待任务被执行;
基于文件 Stream 的构建流;
我们可以使用 gulp 的插件体系来完成某些任务;
webpack 的核心理念是module bundler
webpack 是一个模块化的打包工具;
可以使用各种各样的 loader 来加载不同的模块;
可以使用各种各样的插件在 webpack 打包的生命周期完成其他的任务;
gulp 相对于 webpack 的优缺点:
gulp 相对于 webpack 思想更加的简单、易用,更适合编写一些自动化的任务;
但是目前对于大型项目(Vue、React、Angular)并不会使用 gulp 来构建,比如默认 gulp 是不支持模块化的;
基本使用
Gulp 基本使用
依赖包: gulp:是一个流行的任务自动化工具,主要用于前端开发中的构建和优化工作。它基于 Node.js,使用流(streams)来处理文件,使得构建过程更高效。
1、安装 gulp
# 全局安装
npm install gulp -g
# 局部安装
npm install gulp2、编写 gulpfile.js 文件,在其中创建一个任务。
注意: gulpfile.js 文件名是固定的。

3、执行 gulp 命令
npx gulp foo4、返回结果

5、gulp 任务函数需要执行 callback 回调,任务才能结束


6、异步任务

语法
创建任务
每个 gulp 任务都是一个异步的 JS 函数:
Gulp任务结束条件:
- 函数接受一个 callback 作为参数,调用 callback 函数那么任务就会结束。
- 返回stream、promise、event emitter、child process 或 observable 类型的函数。
任务可以是 public 或者 private 类型的:
公开任务(Public tasks) 从 gulpfile 中被导出(module.exports),可以通过 gulp 命令直接调用;
私有任务(Private tasks) 被设计为在内部使用,通常作为 series() 或 parallel() 组合的组成部分;
补充:gulp4 之前, 注册任务时通过 gulp.task 的方式进行注册的

默认任务
默认任务:
- 可以在
gulpfile.js中使用exports.default来定义默认任务。 - 默认任务可以包含其他任务的组合,使用
series(顺序执行)或parallel(并行执行)方法。 - 当运行
gulp命令时,Gulp 会自动执行这个默认任务。
exports.default = (callback) => void
module.exports.default = (callback) => void示例:
1、我们可以编写一个默认任务


2、执行 gulp 命令
npx gulp任务组合
- gulp.series():
(task1, task2, ...),按顺序执行任务。- task1...:
string | function,需要按顺序执行的任务名或任务函数。 - 返回:
- tasks:
function,执行任务的函数。
- task1...:
- gulp.parallel():
(task1, task2, ...),并行执行任务。- task1...:
string | function,需要按顺序执行的任务名或任务函数。 - 返回:
- tasks:
function,执行任务的函数。
- task1...:
通常一个函数中能完成的任务是有限的(放到一个函数中也不方便代码的维护),所以我们会将任务进行组合。
gulp 提供了两个强大的组合方法:
series():串行任务组合。
parallel():并行任务组合。

示例: 串行任务

示例: 并行任务


文件操作
读取、写入文件
- gulp.src():
(glob, options?),读取文件并返回流。- glob:
string | string[],文件模式,支持 glob 匹配。 - options?:
{base,cwd},可选配置,如base和cwd。 - 返回:
- stream:
NodeJS.ReadWriteStream,读取流。
- glob:
- gulp.dest():
(path, options?),将流写入目标目录。- path:
string,目标目录。 - options?:
{base,cwd},可选配置,如base和cwd。 - 返回:
- stream:
NodeJS.ReadWriteStream,可写流。
- path:
- stream.pipe():
(transform),将流传递给下一个处理步骤。常用于插件链式操作。- transform:
stream.Transform,变换流,如插件。
- transform:
思路:
gulp 暴露了 src() 和 dest() 方法用于处理计算机上存放的文件。
src() 接受参数,并从文件系统中读取文件然后生成一个 Node 流(Stream),它将所有匹配的文件读取到内存中并通过流(Stream)进行处理;
由 src() 产生的流(stream)应当从任务(task 函数)中返回并发出异步完成的信号;
dest() 接受一个输出目录作为参数,并且它还会产生一个 Node 流(stream),通过该流将内容输出到文件中;
流(stream)所提供的主要的 API 是 pipe() 方法,pipe 方法的原理是什么呢?
pipe 方法接受一个 转换流(Transform streams)或可写流(Writable streams);
那么转换流或者可写流,拿到数据之后可以对数据进行处理,再次传递给下一个转换流或者可写流;
示例: 基本使用,拷贝单个 js 文件

示例: 拷贝 glob 匹配到的多个 js 文件

文件转换
依赖包:
- gulp-babel:Gulp 插件,用于将 Babel 转换的功能集成到 Gulp 流程中。
- 安装:
pnpm i gulp-babel -D
- 安装:
- gulp-terser:Gulp 插件,接收配置选项来控制压缩行为。
- 安装:
pnpm i gulp-terser -D
- 安装:
如果在这个过程中,我们希望对文件进行某些处理,可以使用社区给我们提供的插件。
比如我们希望 ES6 转换成 ES5,那么可以使用 babel 插件;
如果我们希望对代码进行压缩和丑化,那么可以使用 uglify 或者 terser 插件;
1、使用 babel 转化代码

2、使用 terser 压缩、混淆代码

文件监听
- gulp.watch():
(glob, tasks),监视文件变化并重新运行任务。- glob:
string | string[],监视的文件模式。 - tasks:
string | string[] | function,任务名或任务函数。 - 返回:
- gulp-watch:``,监视流。
- glob:
gulp api 中的 watch() 方法 利用文件系统的监控程序(file system watcher) 与之进行关联。
说明:当./src/**/*.js中的文件发生变化时,会重新运行jsTask任务打包项目

案例:Gulp 构建项目
依赖包:
- gulp-htmlmin:是一个用于在使用 Gulp 构建工具时对 HTML 文件进行压缩的插件。它基于
html-minifier库。- 安装:
pnpm i gulp-htmlmin -D
- 安装:
- gulp-less:是一个用于 Gulp 的 LESS 插件,主要用于将 LESS 文件编译成 CSS 文件。
- 安装:
pnpm i gulp-less -D
- 安装:
- gulp-inject:是一个用于 Gulp 的插件,可以将样式表、JavaScript 和 Web 组件的引用注入到 HTML 文件中,避免手动编辑 index.html 文件。
- 安装:
pnpm i gulp-inject -D
- 安装:
接下来,我们编写一个案例,通过 gulp 来开启本地服务和打包:
1、打包 html 文件:gulp-htmlmin
注意: 配置项见:new HtmlWebpackPlugin({minify})


2、打包 JavaScript 文件:gulp-babel,gulp-terser


3、打包 less 文件:gulp-less


4、将资源注入 html:gulp-inject
在 html 文件中添加占位

添加 inject 任务

注入效果

5、创建打包任务
创建打包任务

执行
npx gulp finalTask开始打包
打包效果

问题: 打包后的引用路径有问题,不能写成绝对路径

解决:在 injectTask 任务中,添加
relative: true参数
效果:

6、监听文件变化,重新构建项目

7、开启本地服务器: browser-sync
注意: browser-sync 是第三方的插件,不是 Gulp 的插件

运行脚本
执行 serveTask,开启本地服务
shnpx gulp serveTask在
package.json中编写 scripts
运行
npm run build或npm run servesh# 执行打包任务 npm run build # 运行本地服务器 npm run serve
8、完整代码


库打包工具 Rollup
概述
我们来看一下官方对 rollup 的定义:
Rollup is a module bundler for JavaScript which compiles small pieces of code into something larger and more complex,such as a library or application.
Rollup 是一个JS 的模块化打包工具,可以帮助我们编译小的代码到一个大的、复杂的代码中,比如一个库或者一个应用程序。
Rollup VS Webpack:
我们会发现 Rollup 的定义、定位和 webpack 非常的相似:
Rollup 也是一个模块化的打包工具,但是 Rollup 主要是针对 ES Module 进行打包的;
webpack 通常可以通过各种 loader 处理各种各样的文件,以及处理它们的依赖关系;
rollup 更多时候是专注于处理 JS 代码的(当然也可以处理 css、font、vue 等文件);
rollup 的配置和理念相对于 webpack 来说,更加的简洁和容易理解;
早期 webpack 不支持 tree shaking 时,rollup 具备更强的优势;
目前 webpack 和 rollup 分别有什么应用场景呢?
通常在实际项目开发过程中,我们都会使用 webpack(比如 react、angular 项目都是基于 webpack 的);
在对库文件进行打包时,我们通常会使用 rollup(比如 vue、react、dayjs 源码本身都是基于 rollup 的,Vite 底层使用 Rollup);
Rollup 基本使用
命令行语法
npx rollup <file> -f iife -o <bundle><file>:string,需要打包的文件。-f <mode>:iife | amd | cjs | umd,打包选项。iife:打包浏览器的库amd:打包 AMD 库cjs:打包 CommonJS 库umd:打包通用库,需要跟上--name
-o <bundle>:string,指定打包后的输出目录。- sh
# 打包浏览器的库 -f iife npx rollup ./src/main.js -f iife -o dist/bundle.js # 打包 AMD 的库 -f amd npx rollup ./src/main.js -f amd -o dist/bundle.js # 打包 CommonJS 的库 -f cjs npx rollup ./src/main.js -f cjs -o dist/bundle.js # 打包通用的库(必须跟上 name) -f umd --name mathUtil npx rollup ./src/main.js -f umd --name mathUtil -o dist/bundle.js
基本使用
1、安装 rollup:
# 全局安装
npm install rollup -g
# 局部安装
npm install rollup -D2、创建 lib/index.js 文件

3、通过命令行打包
npx rollup ./lib/index.js -o dist/bundle.js4、打包时区分不同的环境
# 打包浏览器的库 -f iife
npx rollup ./src/main.js -f iife -o dist/bundle.js
# 打包 AMD 的库 -f amd
npx rollup ./src/main.js -f amd -o dist/bundle.js
# 打包 CommonJS 的库 -f cjs
npx rollup ./src/main.js -f cjs -o dist/bundle.js
# 打包通用的库(必须跟上 name) -f umd --name mathUtil
npx rollup ./src/main.js -f umd --name mathUtil -o dist/bundle.js5、通用环境时的打包结果

配置文件
- input:
string | string[],入口文件路径 - output:
{file, format, name} | {file, format, name}[],输出配置,如文件路径、格式等。- file:
string,打包输出文件名。 - format:
amd | cjs | iife | umd,打包环境格式,amd:AMD 格式cjs:CommonJS 格式iife:立即执行函数,适用于浏览器环境umd:通用环境格式(推荐)
- name:
string,全局名称。适用于 iife 和 umd 格式
- file:
1、将配置信息写到配置文件中 rollup.config.js 文件:

2、可以对文件进行分别打包,打包出更多的库文件(用户可以根据不同的需求来引入):

打包结果:

常见插件
解决 CJS 和第三方库问题
问题: 当项目中使用了第三方库(如 lodash)时,由于 lodash 使用的是module.exports向外导出。而module.exports是 commonjs 的导出方式,rollup 默认只会处理 es module 的语法。所欲 lodash 是不会被 rollup 打包的。
解决:需要安装额外的插件,让 rollup 支持打包 commonjs 语法。
1、安装解决 commonjs 的库:@rollup/plugin-commonjs
npm install @rollup/plugin-commonjs -D2、安装解析 node_modules 的库:@rollup/plugin-node-resolve
npm install @rollup/plugin-node-resolve -D3、配置插件

4、实际开发中,库文件我们是不需要对 lodash 进行打包的,此时可以在配置中排除 lodash 打包

Babel 转换代码
如果我们希望将 ES6 转成 ES5 的代码,可以在 rollup 中使用 babel。
1、安装 rollup 对应的 babel 插件:@rollup/plugin-babel
npm install @rollup/plugin-babel -D2、修改配置文件:
需要配置 babel.config.js 文件

babelHelpers

Teser 代码压缩
如果我们希望对代码进行压缩,可以使用@rollup/plugin-terser
1、安装插件
npm install @rollup/plugin-terser -D2、配置 terser


打包 CSS
处理 css 文件
1、如果我们项目中需要处理 css 文件,可以使用 postcss
npm install rollup-plugin-postcss postcss -D2、配置 postcss 的插件

3、打包效果

4、为 postcss 添加 postcss-preset-env 配置



打包 Vue
处理 vue 文件
依赖包:
- rollup-plugin-vue:``,
- @vue/compiler-sfc:``,
1、处理 vue 文件我们需要使用 rollup-plugin-vue 插件
注意: 默认情况下我们安装的是 vue3.x 的版本,所以我这里指定了一下 rollup-plugin-vue 的版本;
npm install rollup-plugin-vue @vue/compiler-sfc -D2、使用 vue 的插件

3、在我们打包 vue 项目后,运行会报如下的错误:

这是因为在我们打包的 vue 代码中,用到 process.env.NODE_ENV,所以我们可以使用一个插件 @rollup/plugin-replace 设置它对应的值:
npm install @rollup/plugin-replace -D配置插件信息:

本地服务器
依赖包:
- rollup-plugin-serve:``,
- rollup-plugin-livereload:``,
1、使用 rollup-plugin-serve 搭建服务
npm install rollup-plugin-serve -D
2、当文件发生变化时,自动刷新浏览器
npm install rollup-plugin-livereload -D
3、启动时,开启文件监听
npx rollup -c -w环境区分
1、在 package.json 中创建一个开发和构建的脚本:

2、根据不同的环境,设置不同的配置项

快速开发工具 Vite
概述
认识 Vite
什么是 vite 呢?
- 官方的定位:下一代前端开发与构建工具;
如何定义下一代开发和构建工具呢?
我们知道在实际开发中,我们编写的代码往往是不能被浏览器直接识别的,比如 ES6、TypeScript、Vue 文件等等;
所以我们必须通过构建工具来对代码进行转换、编译,类似的工具有 webpack、rollup、parcel;
但是随着项目越来越大,需要处理的 JavaScript 呈指数级增长,模块越来越多;
构建工具需要很长的时间才能开启服务器,HMR 也需要几秒钟才能在浏览器反应出来;
所以也有这样的说法:天下苦 webpack 久矣;
Vite (法语意为 "快速的",发音 /vit/) 是一种新型前端构建工具,能够显著提升前端开发体验。

Vite 构造
它主要由两部分组成:
一个开发服务器,它基于原生 ES 模块提供了丰富的内建功能,HMR 的速度非常快速;
一套构建指令,它使用 rollup 打开我们的代码,并且它是预配置的,可以输出生产环境的优化过的静态资源;
在浏览器支持 ES 模块之前,JavaScript 并没有提供原生机制让开发者以模块化的方式进行开发。
这也正是我们对 “打包” 这个概念熟悉的原因:使用工具抓取、处理并将我们的源码模块串联成可以在浏览器中运行的文件。
时过境迁,我们见证了诸如 webpack、Rollup和 Parcel等工具的变迁,它们极大地改善了前端开发者的开发体验。
然而,当我们开始构建越来越大型的应用时,需要处理的 JavaScript 代码量也呈指数级增长。包含数千个模块的大型项目相当普遍。
基于 JavaScript 开发的工具就会开始遇到性能瓶颈:通常需要很长时间(甚至是几分钟!)才能启动开发服务器,即使使用模块热替换(HMR),文件修改后的效果也需要几秒钟才能在浏览器中反映出来。
Vite 旨在利用生态系统中的新进展解决上述问题:
浏览器开始原生支持 ES 模块,且越来越多 JavaScript 工具使用编译型语言编写。
the rise of JavaScript tools written in compile-to-native languages.
浏览器原生支持模块化
直接使用 ES Module 开发:
不借助于其他工具,直接使用 ES Module 来开发项目。
1、引入 js 脚本时,需要添加type="module"告诉浏览器当前 JS 是模块化代码

2、在加载其他 JS 模块时不能省略后缀名

3、如果项目中使用了第三方库(如lodash-es),需要如下引入

直接使用 ES Module 开发的缺点:
但是如果我们不借助于其他工具,直接使用 ES Module 来开发有什么问题呢?
1、必须明确写上后缀名。
2、我们会发现在使用 loadash 时,加载了上百个模块的 js 代码,对于浏览器发送请求是巨大的消耗。
3、我们的代码中如果有 TypeScript、less、vue 等代码时,浏览器并不能直接识别。
事实上,vite 就帮助我们解决了上面的所有问题。
Vite 优点
1、不需要添加后缀名

2、加载第三方库不需要加载库内部引入的众多模块


3、增加了对 TS、Vue、React 的识别支持

Vite 打包
Vite 安装
1、我们安装一下 vite 工具
npm install vite –g
# 局部安装(推荐)
npm install vite -D2、通过 vite 来启动项目
npx viteVite 对 css 的支持
1、vite 可以直接支持 css 的处理
- 直接导入 css 即可;
2、vite 可以直接支持 css 预处理器,比如 less
直接导入 less;
之后安装 less 编译器;
npm install less -D3、vite 直接支持 postcss 的转换:
- 只需要安装 postcss,并且配置
postcss.config.js的配置文件即可;
npm install postcss postcss-preset-env -D

Vite 对 TypeScript 的支持
vite 对 TypeScript 是原生支持的,它会直接使用 ESBuild 来完成编译,只需要直接导入即可。
如果我们查看浏览器中的请求,会发现请求的依然是 ts 的代码:
这是因为 vite 中的服务器 Connect 会对我们的请求进行转发;
获取 ts 编译后的代码,给浏览器返回,浏览器可以直接进行解析;
虽然请求的是 TS 文件,但是内容已经是转化后的 JS 代码了

注意: 在 vite2 中,已经不再使用 Koa 了,而是使用 Connect 来搭建的服务器。这是因为 vite 中主要的都是请求转发业务,没有必要使用 Koa。

Vite 对 vue 的支持
vite 对 vue 提供第一优先级支持:
Vue3 单文件组件支持:@vitejs/plugin-vue (2024-9-10: 目前已经不需要该插件)
Vue3 JSX 支持:@vitejs/plugin-vue-jsx
Vue2 支持:underfin/vite-plugin-vue2
1、安装支持 vue 的插件:
npm install @vitejs/plugin-vue -D2、在 vite.config.js 中配置插件:(配置的写法和 rollup 相似)


Vite 对 react 的支持
.jsx 和 .tsx 文件同样开箱即用,它们也是通过 ESBuild 来完成的编译:
所以我们只需要直接编写 react 的代码即可;


注意: 在 index.html 加载 main.js 时,我们需要将 main.js 的后缀,修改为 main.jsx 作为后缀名;

Vite 打包项目
1、我们可以直接通过 vite build 来完成对当前项目的打包工具:
npx vite build
2、我们可以通过 vite preview 的方式,开启一个本地服务来预览打包后的效果:
npx vite preview注意: vite 打包底层是使用的 Rollup

Vite 脚手架工具
Vite 脚手架: create-vite
在开发中,我们不可能所有的项目都使用 vite 从零去搭建,比如一个 react 项目、Vue 项目;
- 这个时候 vite 还给我们提供了对应的脚手架工具;
所以 Vite 实际上是有两个工具的:
vite:构件工具。类似于 webpack、rollup;
create-vite:vite 的脚手架工具。类似 vue-cli、create-react-app;
如果使用脚手架工具呢?
npm create vite
yarn create vite
pnpm create vite

EsBuild
ESBuild 解析
ESBuild 的特点:
超快的构建速度,并且不需要缓存;
支持 ES6 和 CommonJS 的模块化;
支持 ES6 的 Tree Shaking;
支持 Go、JavaScript 的 API;
支持 TypeScript、JSX 等语法编译;
支持 SourceMap;
支持代码压缩;
支持扩展其他插件;
ESBuild 的构建速度
ESBuild 的构建速度和其他构建工具速度对比:

ESBuild 为什么这么快呢?
使用 Go 语言编写的,可以直接转换成机器代码,而无需经过字节码;
ESBuild 可以充分利用 CPU 的多内核,尽可能让它们饱和运行;
ESBuild 的所有内容都是从零开始编写的,而不是使用第三方,所以从一开始就可以考虑各种性能问题;
等等....